package com.xlf.service.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xlf.common.auth.util.SecurityUtils;
import com.xlf.common.core.constant.Constants;
import com.xlf.common.core.exception.BizException;
import com.xlf.common.core.pojo.vo.UserVO;
import com.xlf.common.core.util.BeanCopyUtils;
import com.xlf.common.core.util.StringUtils;
import com.xlf.common.core.util.page.PageUtils;
import com.xlf.common.redis.service.RedisCache;
import com.xlf.service.blog.domain.Article;
import com.xlf.service.blog.domain.Comment;
import com.xlf.service.blog.domain.dto.AddCommentDTO;
import com.xlf.service.blog.domain.dto.CommentDTO;
import com.xlf.service.blog.mapper.ArticleMapper;
import com.xlf.service.blog.service.CommentService;
import com.xlf.service.blog.mapper.CommentMapper;
import com.xlf.service.system.service.impl.CommonUserVOService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 小新
* @description 针对表【t_comment】的数据库操作Service实现
* @createDate 2023-07-08 16:10:18
*/
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment>
    implements CommentService {

    @Resource
    ArticleMapper articleMapper;

    @Autowired
    RedisCache redisCache;

    @Autowired
    CommonUserVOService commonUserVOService;

    @Override
    public List<Comment> getPage(CommentDTO commentDTO) {

        if(commentDTO.getCommentType() == 1){
            Article article = articleMapper.selectById(commentDTO.getTypeId());
            if(article == null)
                throw new BizException("文章不存在");
            if(article.getStatus() == Constants.EXCEPTION)
                throw new BizException("文章已被删除");
            if(article.getIsComment() == 0)
                throw new BizException("文章未开启评论");
        }

        LambdaQueryChainWrapper<Comment> lambdaQueryChainWrapper = lambdaQuery()
                .eq(Comment::getParentId, 0)
                .eq(Comment::getCommentType, commentDTO.getCommentType())
                .eq(Comment::getTypeId, commentDTO.getTypeId())
                .eq(Comment::getStatus, Constants.NORMAL);

        lambdaQueryChainWrapper.orderByDesc(Comment::getId);

        PageUtils.startPage();
        List<Comment> list = lambdaQueryChainWrapper.list();
        if (StringUtils.isNotEmpty(list)) {
            setCommentChildren(list);
            setUserInfo(list);
        }
        return list;
    }

    @Override
    public Comment addComment(AddCommentDTO commentDTO) {

        Long userId = (Long) SecurityUtils.getUserId();

        Comment comment = BeanCopyUtils.copyObject(commentDTO, Comment.class);

        comment.setFromUid(userId);
        comment.setIsCheck(1);
        comment.setStatus(Constants.NORMAL);
        comment.setCreateTime(new Date());
        save(comment);

        ArrayList<Comment> comments = new ArrayList<>(1);
        comments.add(comment);
        setUserInfo(comments);
        return comment;

    }

    @Override
    public void delComment(Long id) {

        Comment comment = getOne(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getId, id)
                .select(Comment::getFromUid));

        if(comment == null)
            throw new BizException("评论不存在");

        Long userId = (Long)SecurityUtils.getUserId();
        if(!SecurityUtils.isAdmin(userId) && !userId.equals(comment.getFromUid()))
            throw new BizException("没有权限进行删除！");

        lambdaUpdate().set(Comment::getStatus,Constants.EXCEPTION).eq(Comment::getId, id).update();
    }

    @Override
    public List<Comment> getList(Comment comment) {

        List<Comment> comments = Optional.ofNullable(lambdaQuery().setEntity(comment).like(StringUtils.isNotEmpty(comment.getSearchValue()),
                Comment::getCommentContent, comment.getSearchValue())
                .between(StringUtils.isNotEmpty(comment.getParams()) &&
                                comment.getParams().get("beginTime") != null && comment.getParams().get("endTime") != null,
                        Comment::getCreateTime, comment.getParams().get("beginTime"),
                        comment.getParams().get("endTime"))
                .list()).orElse(new ArrayList<>());
        setUserInfo(comments);
        return comments;
    }

    private void setCommentChildren(List<Comment> list) {

        list.forEach(item -> {
            LambdaQueryWrapper<Comment> c_wrapper = new LambdaQueryWrapper<>();
            c_wrapper.eq(Comment::getReplyId, item.getId())
                    .eq(Comment::getCommentType, item.getCommentType())
                    .eq(Comment::getTypeId, item.getTypeId())
                    .eq(Comment::getStatus, Constants.NORMAL)
                    .orderByDesc(Comment::getId);
            List<Comment> comments = list(c_wrapper);
            if (StringUtils.isNotEmpty(comments)) {
                item.setChildren(comments);
            }
        });
    }

    private void setUserInfo(List<Comment> list) {

        if(StringUtils.isEmpty(list))
                return;
        //父评论
        Set<String> u1s = list.stream().filter(item -> item.getFromUid()!=null)
                .map(item -> item.getFromUid().toString()).collect(Collectors.toSet());

        //子评论
        list.forEach(item->{
            List<Comment> comments = item.getChildren();
            if(StringUtils.isNotEmpty(comments)){
                Set<String> u3s = comments.stream().filter(item2 -> item2.getFromUid()!=null)
                        .map(item2 -> item2.getFromUid().toString()).collect(Collectors.toSet());
                Set<String> u4s = comments.stream().filter(item2 -> item2.getToUid()!=null)
                        .map(item2 -> item2.getToUid().toString()).collect(Collectors.toSet());
                u1s.addAll(u3s);
                u1s.addAll(u4s);
            }
        });

        //获取用户
        Map<Long, UserVO> userMap = commonUserVOService.getUserInfoMap(u1s);

        list.forEach(item->{
            item.setFromUser(userMap.get(item.getFromUid()));
            item.setToUser(userMap.get(item.getToUid()));
            List<Comment> comments = item.getChildren();
            if(StringUtils.isNotEmpty(comments)){
                comments.forEach(children->{
                    children.setFromUser(userMap.get(children.getFromUid()));
                    children.setToUser(userMap.get(children.getToUid()));
                });
            }
        });
    }

}


